home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Musique / Quod Libet / quodlibet-3.3.0-installer.exe / bin / sgmllib.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2014-12-31  |  14KB  |  553 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.7)
  3.  
  4. '''A parser for SGML, using the derived class as a static DTD.'''
  5. from warnings import warnpy3k
  6. warnpy3k('the sgmllib module has been removed in Python 3.0', stacklevel = 2)
  7. del warnpy3k
  8. import markupbase
  9. import re
  10. __all__ = [
  11.     'SGMLParser',
  12.     'SGMLParseError']
  13. interesting = re.compile('[&<]')
  14. incomplete = re.compile('&([a-zA-Z][a-zA-Z0-9]*|#[0-9]*)?|<([a-zA-Z][^<>]*|/([a-zA-Z][^<>]*)?|![^<>]*)?')
  15. entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]')
  16. charref = re.compile('&#([0-9]+)[^0-9]')
  17. starttagopen = re.compile('<[>a-zA-Z]')
  18. shorttagopen = re.compile('<[a-zA-Z][-.a-zA-Z0-9]*/')
  19. shorttag = re.compile('<([a-zA-Z][-.a-zA-Z0-9]*)/([^/]*)/')
  20. piclose = re.compile('>')
  21. endbracket = re.compile('[<>]')
  22. tagfind = re.compile('[a-zA-Z][-_.a-zA-Z0-9]*')
  23. attrfind = re.compile('\\s*([a-zA-Z_][-:.a-zA-Z_0-9]*)(\\s*=\\s*(\\\'[^\\\']*\\\'|"[^"]*"|[][\\-a-zA-Z0-9./,:;+*%?!&$\\(\\)_#=~\\\'"@]*))?')
  24.  
  25. class SGMLParseError(RuntimeError):
  26.     '''Exception raised for all parse errors.'''
  27.     pass
  28.  
  29.  
  30. class SGMLParser(markupbase.ParserBase):
  31.     entity_or_charref = re.compile('&(?:([a-zA-Z][-.a-zA-Z0-9]*)|#([0-9]+))(;?)')
  32.     
  33.     def __init__(self, verbose = 0):
  34.         '''Initialize and reset this instance.'''
  35.         self.verbose = verbose
  36.         self.reset()
  37.  
  38.     
  39.     def reset(self):
  40.         '''Reset this instance. Loses all unprocessed data.'''
  41.         self._SGMLParser__starttag_text = None
  42.         self.rawdata = ''
  43.         self.stack = []
  44.         self.lasttag = '???'
  45.         self.nomoretags = 0
  46.         self.literal = 0
  47.         markupbase.ParserBase.reset(self)
  48.  
  49.     
  50.     def setnomoretags(self):
  51.         '''Enter literal mode (CDATA) till EOF.
  52.  
  53.         Intended for derived classes only.
  54.         '''
  55.         self.nomoretags = self.literal = 1
  56.  
  57.     
  58.     def setliteral(self, *args):
  59.         '''Enter literal mode (CDATA).
  60.  
  61.         Intended for derived classes only.
  62.         '''
  63.         self.literal = 1
  64.  
  65.     
  66.     def feed(self, data):
  67.         """Feed some data to the parser.
  68.  
  69.         Call this as often as you want, with as little or as much text
  70.         as you want (may include '
  71. ').  (This just saves the text,
  72.         all the processing is done by goahead().)
  73.         """
  74.         self.rawdata = self.rawdata + data
  75.         self.goahead(0)
  76.  
  77.     
  78.     def close(self):
  79.         '''Handle the remaining data.'''
  80.         self.goahead(1)
  81.  
  82.     
  83.     def error(self, message):
  84.         raise SGMLParseError(message)
  85.  
  86.     
  87.     def goahead(self, end):
  88.         rawdata = self.rawdata
  89.         i = 0
  90.         n = len(rawdata)
  91.         while i < n:
  92.             if self.nomoretags:
  93.                 self.handle_data(rawdata[i:n])
  94.                 i = n
  95.                 break
  96.             match = interesting.search(rawdata, i)
  97.             if match:
  98.                 j = match.start()
  99.             else:
  100.                 j = n
  101.             if i < j:
  102.                 self.handle_data(rawdata[i:j])
  103.             i = j
  104.             if i == n:
  105.                 break
  106.             if rawdata[i] == '<':
  107.                 if starttagopen.match(rawdata, i):
  108.                     if self.literal:
  109.                         self.handle_data(rawdata[i])
  110.                         i = i + 1
  111.                         continue
  112.                     k = self.parse_starttag(i)
  113.                     if k < 0:
  114.                         break
  115.                     i = k
  116.                     continue
  117.                 if rawdata.startswith('</', i):
  118.                     k = self.parse_endtag(i)
  119.                     if k < 0:
  120.                         break
  121.                     i = k
  122.                     self.literal = 0
  123.                     continue
  124.                 if self.literal:
  125.                     if n > i + 1:
  126.                         self.handle_data('<')
  127.                         i = i + 1
  128.                         continue
  129.                     break
  130.                     continue
  131.                 if rawdata.startswith('<!--', i):
  132.                     k = self.parse_comment(i)
  133.                     if k < 0:
  134.                         break
  135.                     i = k
  136.                     continue
  137.                 if rawdata.startswith('<?', i):
  138.                     k = self.parse_pi(i)
  139.                     if k < 0:
  140.                         break
  141.                     i = i + k
  142.                     continue
  143.                 if rawdata.startswith('<!', i):
  144.                     k = self.parse_declaration(i)
  145.                     if k < 0:
  146.                         break
  147.                     i = k
  148.                     continue
  149.                 
  150.             elif rawdata[i] == '&':
  151.                 if self.literal:
  152.                     self.handle_data(rawdata[i])
  153.                     i = i + 1
  154.                     continue
  155.                 match = charref.match(rawdata, i)
  156.                 if match:
  157.                     name = match.group(1)
  158.                     self.handle_charref(name)
  159.                     i = match.end(0)
  160.                     if rawdata[i - 1] != ';':
  161.                         i = i - 1
  162.                         continue
  163.                         continue
  164.                 match = entityref.match(rawdata, i)
  165.                 if match:
  166.                     name = match.group(1)
  167.                     self.handle_entityref(name)
  168.                     i = match.end(0)
  169.                     if rawdata[i - 1] != ';':
  170.                         i = i - 1
  171.                         continue
  172.                         continue
  173.                     
  174.                 else:
  175.                     self.error('neither < nor & ??')
  176.             match = incomplete.match(rawdata, i)
  177.             if not match:
  178.                 self.handle_data(rawdata[i])
  179.                 i = i + 1
  180.                 continue
  181.             j = match.end(0)
  182.             if j == n:
  183.                 break
  184.             self.handle_data(rawdata[i:j])
  185.             i = j
  186.         if end and i < n:
  187.             self.handle_data(rawdata[i:n])
  188.             i = n
  189.         self.rawdata = rawdata[i:]
  190.  
  191.     _decl_otherchars = '='
  192.     
  193.     def parse_pi(self, i):
  194.         rawdata = self.rawdata
  195.         if rawdata[i:i + 2] != '<?':
  196.             self.error('unexpected call to parse_pi()')
  197.         match = piclose.search(rawdata, i + 2)
  198.         if not match:
  199.             return -1
  200.         j = None.start(0)
  201.         self.handle_pi(rawdata[i + 2:j])
  202.         j = match.end(0)
  203.         return j - i
  204.  
  205.     
  206.     def get_starttag_text(self):
  207.         return self._SGMLParser__starttag_text
  208.  
  209.     
  210.     def parse_starttag(self, i):
  211.         self._SGMLParser__starttag_text = None
  212.         start_pos = i
  213.         rawdata = self.rawdata
  214.         if shorttagopen.match(rawdata, i):
  215.             match = shorttag.match(rawdata, i)
  216.             if not match:
  217.                 return -1
  218.             (tag, data) = None.group(1, 2)
  219.             self._SGMLParser__starttag_text = '<%s/' % tag
  220.             tag = tag.lower()
  221.             k = match.end(0)
  222.             self.finish_shorttag(tag, data)
  223.             self._SGMLParser__starttag_text = rawdata[start_pos:match.end(1) + 1]
  224.             return k
  225.         match = None.search(rawdata, i + 1)
  226.         if not match:
  227.             return -1
  228.         j = None.start(0)
  229.         attrs = []
  230.         if rawdata[i:i + 2] == '<>':
  231.             k = j
  232.             tag = self.lasttag
  233.         else:
  234.             match = tagfind.match(rawdata, i + 1)
  235.             if not match:
  236.                 self.error('unexpected call to parse_starttag')
  237.             k = match.end(0)
  238.             tag = rawdata[i + 1:k].lower()
  239.             self.lasttag = tag
  240.         while k < j:
  241.             match = attrfind.match(rawdata, k)
  242.             if not match:
  243.                 break
  244.             (attrname, rest, attrvalue) = match.group(1, 2, 3)
  245.             if not rest:
  246.                 attrvalue = attrname
  247.             elif "'" == "'":
  248.                 pass
  249.             elif not "'" == "'" == attrvalue[-1:]:
  250.                 if '"' == '"':
  251.                     pass
  252.                 elif '"' == attrvalue[-1:]:
  253.                     attrvalue = attrvalue[1:-1]
  254.                 attrvalue = self.entity_or_charref.sub(self._convert_ref, attrvalue)
  255.                 attrs.append((attrname.lower(), attrvalue))
  256.                 k = match.end(0)
  257.             if rawdata[j] == '>':
  258.                 j = j + 1
  259.             self._SGMLParser__starttag_text = rawdata[start_pos:j]
  260.             self.finish_starttag(tag, attrs)
  261.             return j
  262.  
  263.     
  264.     def _convert_ref(self, match):
  265.         if match.group(2):
  266.             if not self.convert_charref(match.group(2)):
  267.                 pass
  268.             return '&#%s%s' % match.groups()[1:]
  269.         if None.group(3):
  270.             if not self.convert_entityref(match.group(1)):
  271.                 pass
  272.             return '&%s;' % match.group(1)
  273.         return None % match.group(1)
  274.  
  275.     
  276.     def parse_endtag(self, i):
  277.         rawdata = self.rawdata
  278.         match = endbracket.search(rawdata, i + 1)
  279.         if not match:
  280.             return -1
  281.         j = None.start(0)
  282.         tag = rawdata[i + 2:j].strip().lower()
  283.         if rawdata[j] == '>':
  284.             j = j + 1
  285.         self.finish_endtag(tag)
  286.         return j
  287.  
  288.     
  289.     def finish_shorttag(self, tag, data):
  290.         self.finish_starttag(tag, [])
  291.         self.handle_data(data)
  292.         self.finish_endtag(tag)
  293.  
  294.     
  295.     def finish_starttag(self, tag, attrs):
  296.         
  297.         try:
  298.             method = getattr(self, 'start_' + tag)
  299.         except AttributeError:
  300.             
  301.             try:
  302.                 method = getattr(self, 'do_' + tag)
  303.             except AttributeError:
  304.                 self.unknown_starttag(tag, attrs)
  305.                 return -1
  306.  
  307.             self.handle_starttag(tag, method, attrs)
  308.             return 0
  309.  
  310.         self.stack.append(tag)
  311.         self.handle_starttag(tag, method, attrs)
  312.         return 1
  313.  
  314.     
  315.     def finish_endtag(self, tag):
  316.         if not tag:
  317.             found = len(self.stack) - 1
  318.             if found < 0:
  319.                 self.unknown_endtag(tag)
  320.                 return None
  321.         if tag not in self.stack:
  322.             
  323.             try:
  324.                 method = getattr(self, 'end_' + tag)
  325.             except AttributeError:
  326.                 self.unknown_endtag(tag)
  327.  
  328.             self.report_unbalanced(tag)
  329.             return None
  330.         found = None(self.stack)
  331.         for i in range(found):
  332.             if self.stack[i] == tag:
  333.                 found = i
  334.                 continue
  335.         while len(self.stack) > found:
  336.             tag = self.stack[-1]
  337.             
  338.             try:
  339.                 method = getattr(self, 'end_' + tag)
  340.             except AttributeError:
  341.                 method = None
  342.  
  343.             if method:
  344.                 self.handle_endtag(tag, method)
  345.             else:
  346.                 self.unknown_endtag(tag)
  347.             del self.stack[-1]
  348.  
  349.     
  350.     def handle_starttag(self, tag, method, attrs):
  351.         method(attrs)
  352.  
  353.     
  354.     def handle_endtag(self, tag, method):
  355.         method()
  356.  
  357.     
  358.     def report_unbalanced(self, tag):
  359.         if self.verbose:
  360.             print '*** Unbalanced </' + tag + '>'
  361.             print '*** Stack:', self.stack
  362.  
  363.     
  364.     def convert_charref(self, name):
  365.         '''Convert character reference, may be overridden.'''
  366.         
  367.         try:
  368.             n = int(name)
  369.         except ValueError:
  370.             return None
  371.  
  372.         if n <= n:
  373.             pass
  374.         elif not n <= 127:
  375.             return None
  376.         return self.convert_codepoint(n)
  377.  
  378.     
  379.     def convert_codepoint(self, codepoint):
  380.         return chr(codepoint)
  381.  
  382.     
  383.     def handle_charref(self, name):
  384.         '''Handle character reference, no need to override.'''
  385.         replacement = self.convert_charref(name)
  386.         if replacement is None:
  387.             self.unknown_charref(name)
  388.         else:
  389.             self.handle_data(replacement)
  390.  
  391.     entitydefs = {
  392.         'lt': '<',
  393.         'gt': '>',
  394.         'amp': '&',
  395.         'quot': '"',
  396.         'apos': "'" }
  397.     
  398.     def convert_entityref(self, name):
  399.         '''Convert entity references.
  400.  
  401.         As an alternative to overriding this method; one can tailor the
  402.         results by setting up the self.entitydefs mapping appropriately.
  403.         '''
  404.         table = self.entitydefs
  405.         if name in table:
  406.             return table[name]
  407.         return None
  408.  
  409.     
  410.     def handle_entityref(self, name):
  411.         '''Handle entity references, no need to override.'''
  412.         replacement = self.convert_entityref(name)
  413.         if replacement is None:
  414.             self.unknown_entityref(name)
  415.         else:
  416.             self.handle_data(replacement)
  417.  
  418.     
  419.     def handle_data(self, data):
  420.         pass
  421.  
  422.     
  423.     def handle_comment(self, data):
  424.         pass
  425.  
  426.     
  427.     def handle_decl(self, decl):
  428.         pass
  429.  
  430.     
  431.     def handle_pi(self, data):
  432.         pass
  433.  
  434.     
  435.     def unknown_starttag(self, tag, attrs):
  436.         pass
  437.  
  438.     
  439.     def unknown_endtag(self, tag):
  440.         pass
  441.  
  442.     
  443.     def unknown_charref(self, ref):
  444.         pass
  445.  
  446.     
  447.     def unknown_entityref(self, ref):
  448.         pass
  449.  
  450.  
  451.  
  452. class TestSGMLParser(SGMLParser):
  453.     
  454.     def __init__(self, verbose = 0):
  455.         self.testdata = ''
  456.         SGMLParser.__init__(self, verbose)
  457.  
  458.     
  459.     def handle_data(self, data):
  460.         self.testdata = self.testdata + data
  461.         if len(repr(self.testdata)) >= 70:
  462.             self.flush()
  463.  
  464.     
  465.     def flush(self):
  466.         data = self.testdata
  467.         if data:
  468.             self.testdata = ''
  469.             print 'data:', repr(data)
  470.  
  471.     
  472.     def handle_comment(self, data):
  473.         self.flush()
  474.         r = repr(data)
  475.         if len(r) > 68:
  476.             r = r[:32] + '...' + r[-32:]
  477.         print 'comment:', r
  478.  
  479.     
  480.     def unknown_starttag(self, tag, attrs):
  481.         self.flush()
  482.         if not attrs:
  483.             print 'start tag: <' + tag + '>'
  484.         else:
  485.             print 'start tag: <' + tag,
  486.             for name, value in attrs:
  487.                 print name + '=' + '"' + value + '"',
  488.             
  489.             print '>'
  490.  
  491.     
  492.     def unknown_endtag(self, tag):
  493.         self.flush()
  494.         print 'end tag: </' + tag + '>'
  495.  
  496.     
  497.     def unknown_entityref(self, ref):
  498.         self.flush()
  499.         print '*** unknown entity ref: &' + ref + ';'
  500.  
  501.     
  502.     def unknown_charref(self, ref):
  503.         self.flush()
  504.         print '*** unknown char ref: &#' + ref + ';'
  505.  
  506.     
  507.     def unknown_decl(self, data):
  508.         self.flush()
  509.         print '*** unknown decl: [' + data + ']'
  510.  
  511.     
  512.     def close(self):
  513.         SGMLParser.close(self)
  514.         self.flush()
  515.  
  516.  
  517.  
  518. def test(args = None):
  519.     import sys as sys
  520.     if args is None:
  521.         args = sys.argv[1:]
  522.     if args and args[0] == '-s':
  523.         args = args[1:]
  524.         klass = SGMLParser
  525.     else:
  526.         klass = TestSGMLParser
  527.     if args:
  528.         file = args[0]
  529.     else:
  530.         file = 'test.html'
  531.     if file == '-':
  532.         f = sys.stdin
  533.     else:
  534.         
  535.         try:
  536.             f = open(file, 'r')
  537.         except IOError:
  538.             msg = None
  539.             print file, ':', msg
  540.             sys.exit(1)
  541.  
  542.     data = f.read()
  543.     if f is not sys.stdin:
  544.         f.close()
  545.     x = klass()
  546.     for c in data:
  547.         x.feed(c)
  548.     
  549.     x.close()
  550.  
  551. if __name__ == '__main__':
  552.     test()
  553.